<template>
	<div class="content">
		<div class="main">
			<div class="card game-rule">
				<div class="title" @click="reload">使用说明：</div>
				<div class="title">1、打开手机蓝牙和位置权限；</div>
				<div class="title">2、将魔方复原；</div>
				<div class="title">3、点击【连接设备】连接魔方；</div>
				<div class="title">4、点击【重置魔方】；</div>
				<div class="title">5、点击【开始比赛】；</div>
				<div class="title">6、遇到问题，请拍下魔方和屏幕的照片进行反馈。</div>
				
			</div>
			<!-- <div class="card flex">
				<div class="title">获取所有面：</div>
				<button @click="cubeGetFacelets">点击获取</button>
			</div>
			<div class="card flex">
				<div class="title">获取当前还原：</div>
				<button @click="cubeGetFacelets">点击获取</button>
			</div> -->
			<div class="card flex">
				<div class="title">连接魔方：</div>
				<button @click="bleShowScan">连接设备</button>
				<button @click="bleDisconnect">断开设备</button>
			</div>
			
			<div class="card">
				<div class="title">设备信息：</div>
				<code>
					<template v-if="equipment.length">
						设备名：{{ equipment.filter(v => v.model)[0]?.model }},
						版本：{{ equipment.filter(v => v.version)[0]?.version }}
						电量：{{ battery.batteryPower }}
					</template>
				</code>
			</div>
			<div class="card">
				<div class="title flex"><span>还原公式：</span> <button @click="resolveCube">点击获取</button></div>
				<code>
					{{ resolveStr }}
				</code>
			</div>
			
			<div class="card flex blank">
				<div class="title">重置魔方至复原状态：</div>
				<button @click="cubeReset">重置魔方</button>
			</div>
			<div class="card start-game flex" v-if="[0, 4].includes(timeStore.stage)">
				<div class="title">点击开始打乱：</div>
				<button @click="beginGame" v-if="timeStore.stage === 0">开始打乱</button>
				<button @click="beginGame" v-if="timeStore.stage === 4">再次挑战</button>
			</div>
			<div class="card start-game flex" v-if="[0, 4].includes(timeStore.stage)">
				<div class="title">丟步重设：</div>
				<button @click="resetCubeFates">重设</button>
			</div>
			
			<div class="viewBox" v-if="showLine">
				<Chart :data="dataFour1" />
			</div>
			
			<div class="viewBox longtext">
				<!-- {{ cubeStore.cubeFace }} -->
			</div>
			
			<div class="viewBox">
				<!-- <Gyroscope /> -->
				<div class="card cube-box">
					<div class="cube3d"></div>
				</div>
				<div class="card cube-box">
					<Cube />
				</div>
			</div>
			
			<!-- <code>{{ JSON.stringify(cube_generate_scramble) }}</code>
			<code>{{ JSON.stringify(cubeStore.moveList) }}</code>
			<code>{{ JSON.stringify(timeStore.gameStartIndex) }}</code> -->

			<!-- <div class="card">
				<div class="c-box flex">
					<div class="title">生成打乱规则：</div>
					<button @click="cubeGenerateScramble">点击生成</button>
				</div>
				<div class="c-box">
					<code>{{ cube_generate_scramble }}</code>
				</div>
			</div> -->
			<div class="card formulaDisplay blank" v-if="timeStore.stage === 1">
				<div class="timer">
					打乱中 <span class="led">{{ times }}</span>
				</div>
				<FormulaDisplay class="formula-display" v-if="cube_generate_scramble" :formula="cube_generate_scramble"
					@on-done-scramble="onDoneScramble" @on-stop-scramble="onStopScramble" @on-error-count-max="onErrorMax" />
				<button class="btn" color="linear-gradient(299.95deg, #009AFF 23.55%, #00C7FD 78.39%)"
					@click="onGiveUp">放弃</button>
			</div>

			<div class="card blank" v-if="timeStore.stage === 2">
				<div class="timer fixed">
					观察中
					<span class="led">{{ times }}</span>

					<button class="btn" color="linear-gradient(299.95deg, #009AFF 23.55%, #00C7FD 78.39%)"
						@click="onGiveUp">放弃</button>
				</div>
			</div>

			<div class="card blank" v-if="timeStore.stage === 3">
				<div class="timer">
					复原中
					<p class="led">
						{{ formatTime(times) }}
					</p>

					<button class="btn" color="linear-gradient(299.95deg, #009AFF 23.55%, #00C7FD 78.39%)"
						@click="onGiveUp">放弃</button>
				</div>
			</div>

			<div class="card blank result" v-if="timeStore.stage === 4">
				<div class="timer">
					结果
					<p class="msg">
						{{ formatTime(timeStore.gameTime) }}
					</p>

					<div class="msg">步数：{{ timeStore.turn }}</div>
					<div class="msg">TPS：{{ timeStore.tps }}</div>
				</div>
			</div>

			<div class="card blank">
				<div class="race-box blank" v-for="item in timeStore.result" :key="item.iStartTime">
					<div class="title">第{{ item.mRecord.iSession }}场</div>
					<code>
						<p>结束时间：{{ formatDate(item.mRecord.iEndTime) }}</p>
						<p>复原用时：{{ formatTime(item.mRecord.mData.iDuration) }}</p>
						<p>复原用时(间隔累加)：{{ formatTime(timeStore.resultIntervalTime) }}</p>
						<p>复原用时(时间戳)：{{ formatTime(timeStore.resultStampTime) }}</p>
						<p>步数：{{ item.mRecord.mData.iTurn }}</p>
						<p>TPS：{{ item.mRecord.mData.sTPS }}</p>
						<p>打乱公式：{{ item.mRecord.mData.sScramble }}</p>
						<p>复原步骤：{{ item.mRecord.mData.sReduction }}</p>
					</code>
				</div>
			</div>

		</div>
	</div>
</template>

<script setup>
	import {
		ref,
		onMounted,
		watch,
		watchEffect,
	} from 'vue';

	import {
		mCall,
		mBus
	} from '@/utils/mCall.js'
	import {
		CubeMap,
		formatTime,
		formatDate,
		mergeMove,
	} from '@/utils/common.js'
	import VConsole from 'vconsole'
	import FormulaDisplay from "@/components/FormulaDisplay.vue";
	import Cube from "@/components/Cube.vue";
	import Gyroscope from "@/components/Gyroscope.vue"
	import {
		useCubeStore
	} from "@/stores/cube";
	import {
		useTimeStore
	} from "@/stores/time";
	import Chart from '@/components/Echart.vue';
	import cube3d from '@/utils/cube3d.js'
	// import vmCube from '@/utils/cube.js'
	import vmCube from '@/utils/solve.js'

	const cubeStore = useCubeStore();
	const timeStore = useTimeStore();

	const vConsole = new VConsole()
	const VmCube = new vmCube()

	//是否有蓝牙权限
	const ble_has_permission = ref(false)
	//设备是否已连接
	const ble_is_connected = ref(false)
	//生成的打乱规则
	const cube_generate_scramble = ref('')
	// v3版本的数据
	const v3Data = ref('')
	//当前转动的字母代号
	const cubeMoves = ref([])
	// 设备信息
	const equipment = ref([])
	// 电池信息
	const battery = ref({})
	// 陀螺仪dataFour1数据
	const dataFour1 = ref([[], [], [], []])
	// 是否显示折线图
	const showLine = ref(false)
	// 当前飞机图
	const cubeFace = ref('')
	// 还原公式
	const resolveStr = ref('')

	const times = ref(45);
	const moved = ref(false)

	let intervalTimer = undefined
	let watchCompleted = null
	let wait = 0
	let waitTime = 1000
	let cubeGame = null
	let faceLetsTime = 0
	
	const reload = () => {
		window.location.reload(true)
	}
	let startStepJson = ref({})
	let stopStepJson = ref({})

	const parseBoolean = pb => {
		return pb ? '是' : '否'
	}

	const log = (msg) => {
		// console.log(JSON.stringify(msg))
	}

	const cubeGetFacelets = () => {
		mCall('cube_get_facelets')
	}

	const cubeSolveIn = () => {
		mCall('cube_solve_in')
	}

	// 蓝牙是否连接-与蓝牙交互
	const bleIsConnected = () => {
		mCall('ble_is_connected')
	}

	// 是否有蓝牙权限
	const bleHasPermission = () => {
		mCall('ble_has_permission')
	}

	// 打开蓝牙连接面板
	const bleShowScan = () => {
		mCall('ble_show_scan')
		
		equipment.value = []
		if (!equipment.value.length) {
			const inter = setInterval(() => {
				if (equipment.value.length) {
					// mCall('disable_gyroscope', 1)
					clearInterval(inter)
				} else {
					getEquipment()
					getBattery()
				}
			}, 5000)
		}
	}

	// 断开魔方连接
	const bleDisconnect = () => {
		mCall('ble_disconnect', '')
	}

	// 生成打乱规则
	const cubeGenerateScramble = () => {
		mCall('cube_generate_scramble')
	}

	// 魔方复原重置
	const cubeReset = () => {
		mCall('sendJSONData', {
			adress: '',
			data:{
				protoId: 6,
				step: 1,
				count: 28,
			}
		})
		
		cubeGame.facelets.setFaceLets('UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB')
	
		cubeGame.cube.reset()
		
		VmCube.identity()
	}
	
	// 同步魔方当前状态
	const cubeSync = () => {
		mCall('cube_sync')
	}

	// 开始游戏
	const beginGame = () => {
		mCall('cube_generate_scramble')
	}

	const start = () => {
		// console.log('start')
		times.value = 45

		//重置比赛数据
		timeStore.reset();
		timeStore.startScramble(cube_generate_scramble.value);
		
		clearInterval(intervalTimer);
		intervalTimer = setInterval(() => {
			times.value--;
			if (times.value <= 0) {
				times.value = 0;
			}
			if (times.value <= 0) {
				clearInterval(intervalTimer);
				intervalTimer = undefined;
				onStopScramble();
			}
		}, 1000);
		
		mCall('keep_screen_on')
	}

	// 放弃
	const onGiveUp = () => {
		timeStore.endScramble();
		timeStore.giveUp();
		timeStore.checkout(
			cubeStore.moveList,
			cubeStore.moveTimeList,
			cubeStore.model
		);

		clearInterval(intervalTimer);
		intervalTimer = undefined;
		timeStore.reset()
	}

	//打乱结束
	const onStopScramble = () => {
		// console.log("onStopScramble");
		timeStore.endScramble();
		uni.showToast({
			title: '打乱未完成,请重新开始',
			icon: 'none'
		})
		timeStore.reset()
		clearInterval(intervalTimer);
	};

	//开始观察
	const onDoneScramble = () => {
		// console.log("onDoneScramble");
		timeStore.endScramble();
		observe()
	};

	const onErrorMax = () => {
		// console.log("onErrorMax");
		timeStore.endScramble();
		uni.showToast({
			title: '打乱失败,请重新开始',
			icon: 'none'
		})
		timeStore.reset()
		clearInterval(intervalTimer);
	};

	// 观察模块
	const observe = () => {
		times.value = 15

		clearInterval(intervalTimer)
		intervalTimer = setInterval(() => {
			times.value--
			if (times.value <= 0) {
				times.value = 0
			}
			if (times.value <= 0) {
				clearInterval(intervalTimer)
				intervalTimer = undefined
				onStopWatch()
			}
		}, 1000)
	}

	const onStopWatch = (num = 0) => {
		// console.log("onStopWatch");
		timeStore.endWatch(cubeStore.moveList.length + num)
		beginCubing()
	}

	//开始复原
	const beginCubing = () => {
		// console.log("beginCubing");

		clearInterval(intervalTimer)
		times.value = 0
		intervalTimer = setInterval(() => {
			times.value = Date.now() - timeStore.gameStartTime;
			if (times.value > 1000 * 300) {
				clearInterval(intervalTimer)
				uni.showToast({
					title: '超时300秒，自动DNF',
					icon: 'none'
				})
				onGiveUp()
			}
		}, 5);
	}

	// 复原完成
	const onComplete = () => {
		timeStore.endGame(cubeStore.moveList.length);
		clearInterval(intervalTimer);
		intervalTimer = undefined;
		showResult()
	};

	// 显示结果
	const showResult = () => {
		timeStore.checkout(
			cubeStore.moveList,
			cubeStore.moveTimeList,
			cubeStore.model
		);

		// 判断是否作弊
		let isDNF = false
		// console.log('--------', timeStore.tps, timeStore.turn, timeStore.gameTime, cubeStore.cubeFace)
		if (
			(timeStore.tps <= 6 && timeStore.turn <= 27) ||
			timeStore.gameTime <= 2000
		) {
			uni.showToast({
				title: '检测到你本局存在违规行为，比赛成绩判定为DNF',
				icon: 'none'
			})
			isDNF = true
		}
		
		mCall('keep_screen_off')
	}
	
	// 设备信息
	const getEquipment = () => {
		mCall('sendJSONData', {
			adress: '',
			data:{
				protoId: 3,
			}
		})
	}
	
	// 电池电量
	const getBattery = () => {
		mCall('sendJSONData', {
			adress: '',
			data:{
				protoId: 4,
			}
		})
	}
	
	// 丟步重设
	const resetCubeFates = () => {
		cubeGame.facelets.setFaceLetsInPlaying(cubeStore.cubeFace)
		// cubeGame.facelets.setFaceLetsInPlaying('UUFUUFUUFRRRRRRRRRFFDFFDFFDDDBDDBDDBLLLLLLLLLUBBUBBUBB')
	}
	
	// 获取还原公式
	const resolveCube = () => {
		
		uni && uni.showLoading({
			title: '计算中'
		});
		setTimeout(() => {
			vmCube.initSolver()
			resolveStr.value = VmCube.solve();
			uni && uni.hideLoading();
		}, 50)
		
	}
	
	const setFace = (data) => {
		console.log('setFace', data)
		cubeStore.onFace(data)
		cubeGame.facelets.setFaceLetsInPlaying(data)
		const now = Date.now()
		if (now - faceLetsTime > 2000) {
			// cubeGame.facelets.setFaceLetsInPlaying(data)
			faceLetsTime = now
		}
	}
	

	onMounted(() => {
		// test
		// const scramble = JSON.parse("{\"data\":\"B2 U^ L2 D B2 U R2 D2 F R^ B2 U2 B R B D B^ D^ U^\"}")
		// scramble.data = scramble.data.replace(/\^/g, '\'')
		// cube_generate_scramble.value = scramble.data
		// start()
		cubeGame = new cube3d()
		

		
		var c = "R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' R U R' U' ".split(' ')
		// var c = "R".split(' ')
		// var c = "D2 F' U2 F B2 R' F' D' B' U L2 U2 B2 U' F2 D' R2 F2 L2".split(' ')
		var test = function() {
			setTimeout(() => {
				if (c.length) {
					cubeGame.transcube.trans(c[0])
					c.shift()
					test()
				}
			}, 10)
		}
		setTimeout(() => {
			// test()
			// cubeGame.facelets.setFaceLetsInPlaying('UUFUUFUUFRRRRRRRRRFFDFFDFFDDDBDDBDDBLLLLLLLLLUBBUBBUBB')
		}, 1000)

		mBus({
			ble_is_connected(res) {
				ble_is_connected.value = res.data
			},
			ble_has_permission(res) {
				ble_has_permission.value = res.data
			},
			cube_generate_scramble(res) {
				cube_generate_scramble.value = res.data.replace(/\^/g, '\'')
				if ([0, 4].includes(timeStore.stage)) {
					start()
				}
			},
			// 接收转动魔方时的信息V2
			onReceiveJSONData(res) {
				res = res.data ? res.data : res
				if (res) {
					const resStr = JSON.stringify(res)

					switch (+res.protoId) {
						// 转动
						case 1:
							log(res)
							const name = CubeMap[res.formula]
							res.cubeName = name
							
							cubeStore.onMove(res)
							v3Data.value = resStr
							cubeMoves.value.push(name)
							cubeGame.transcube.trans(name)
							mCall('cube_get_facelets')
							mCall('cube_is_solved')
							
							VmCube.move(name)
							console.log('asString:', VmCube.asString())
							setFace(VmCube.asString())
							
							// 观察中
							if (timeStore.stage === 2) {
								onStopWatch(-1)
							}
							
							// 左右转动下一把
							if ([0, 4].includes(timeStore.stage)) {
								if (cubeMoves.value.length > 1) {
									let last = cubeMoves.value[cubeMoves.value.length - 2]
									if (name + '\'' === last || name === last + '\'') {
										cubeMoves.value = []
										// beginGame()
									}
								}
							}
							break;
						// 设备信息
						case 3:
							log(res)
							equipment.value = [...equipment.value, res]
							break;
						// 电池电量
						case 4:
							battery.value = res
							break;
						// 账号绑定
						case 5:
							// accountMsg.value = resStr
							break;
						// 魔方复原重置
						case 6:
							// cubereset.value = resStr
							break;
						// 陀螺仪数据
						case 7:
							const now = Date.now()
							if (now - wait > waitTime) {
								// res.axisAngle1 && cubeStore.setGyroscopes(res.axisAngle1)
								wait = now
							}
							showLine.value = true
							if (res.dataFour1) {
								const arr = []
								dataFour1.value.forEach((v, i) => {
									v.push(res.dataFour1[i].value * (res.dataFour1[i].sign ? -1 : 1))
									v = v.slice(-150)
									arr.push(v)
								})
								dataFour1.value = JSON.parse(JSON.stringify(arr))
							}
							
							
							break;
						// 魔方操作公式历史-v1&v2&v3
						case 9:
							// cubehistory.value = resStr
							break;
						// 停表通知
						case 11:
							log('停表通知')
							log(res)
							if (timeStore.stage === 3) {
								onComplete();
								mCall('cube_get_facelets')
							}
							cubeGame.facelets.setFaceLets('UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB')
						default:
							break;
					}

				}
			},
			cube_get_facelets(res) {
				// console.log('cube_get_facelets', res.data)
				// cubeStore.onFace(res.data)
				// cubeGame.facelets.setFaceLetsInPlaying(res.data)
				// const now = Date.now()
				// if (now - faceLetsTime > 2000) {
				// 	// cubeGame.facelets.setFaceLetsInPlaying(res.data)
				// 	faceLetsTime = now
				// }
				// cubeGame.facelets.setFaceLets(res.data)
			},
			cube_solve_in(res) {
				// console.log('cube_solve_in', res)
			},
			cube_is_solved(res) {
				// console.log('cube_is_solved', res)
				cubeStore.onResolved(res.data)
			},

			cube_get_info(res) {
				// log(JSON.stringify(res))
			},
			sendJSONData(res) {
				// log(JSON.stringify(res))
			},
			cube_sync(res) {
				mCall('cube_get_facelets')
			}

			
			
		})
	})
</script>

<style lang="scss" scoped>
	uni-button {
		margin: 0;
		margin-left: 30rpx;
	}

	.content {
		padding: 30rpx;
		counter-reset: list;
	}

	.flex {
		display: flex;
		align-items: center;
	}

	.flexstart {
		justify-content: flex-start;
	}

	.card {
		margin: 20rpx 0;

		&:first-child {
			margin-top: 0;
		}

		button {
			height: 60rpx;
			line-height: 60rpx;
			font-size: 26rpx;
		}

		> .title {
			min-width: 280rpx;
			line-height: 1.4;
			font-size: 28rpx
		}
	}

	.game-rule {
		margin-bottom: 30rpx;

		.title {
			margin-bottom: 10rpx;
			color: #666;
			font-size: 24rpx;
		}
	}

	.log-box {
		height: 200rpx;

		.log-inner {
			position: fixed;
			left: 0;
			bottom: 0;
			width: 100%;
			height: 200rpx;
			padding: 20rpx 30rpx;
			background: #fff;
			color: #666;
			line-height: 1.4;
			word-break: break-all;
			border: 1rpx solid #eee;
		}

		.log {
			height: 200rpx;
			padding: 10px;
			box-sizing: border-box;
			overflow-y: auto;
			word-break: break-all;

			p {
				margin: 5px 0;
			}
		}

		.clear {
			position: absolute;
			right: 80rpx;
			top: 10rpx;
			z-index: 2;
			width: 120rpx;
			height: 40rpx;
			font-size: 12px;
			line-height: 40rpx;
			opacity: 0.5;
		}
	}

	code {
		display: block;
		width: 80%;
		margin: 10rpx 0;
		padding: 20rpx;
		border-radius: 5px;
		background-color: #f5f5f5;
		font-size: 24rpx;
		word-break: break-word;
	}

	.start-game {
		margin: 50rpx 0;
	}

	.card uni-button.btn {
		display: block;
		height: 40px;
		width: 90%;
		margin: 8px;
		border-radius: 40px;
		line-height: 40px;
		font-size: 17px;
		border: 1px solid rgba(0, 0, 0, 0.2);

		&:after {
			border: none;
		}
	}

	.blank {
		margin-top: 50rpx;
	}
	
	.result {
		.msg {
			margin-top: 10rpx;
			color: #333;
		}
	}
	
	.led {
		margin: 10rpx;
	}
	
	.cube-box {
		display: flex;
		justify-content: center;
		align-items: center;
		width: 200px;
		height: 200px;
		margin: 30px auto;
		background-color: #eee;
		border-radius: 10px;
		
		.cube {
			margin: 0;
		}
		
		.cube3d {
			width: 400px;
			height: 400px;
			transform: scale(0.5);
		}
	}
	
	.longtext {
		word-break: break-all;
	}
</style>